package com.fau.hm.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintViolation;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fau.hm.entity.MedicalAdmin;
import com.fau.hm.entity.MedicalKeyValue;
import com.fau.hm.entity.MedicalLeaveApprove;
import com.fau.hm.entity.MedicalLeaveInfo;
import com.fau.hm.entity.MedicalLeaveNotBy;
import com.fau.hm.service.ILeaveManagerService;
import com.fau.hm.util.Page;
import com.fau.hm.util.ParamUtil;
import com.fau.hm.util.SystemConfig;
import com.fau.hm.util.ValidatorUtil;

@Service
@Transactional(readOnly = true)
public class LeaveManagerService extends BaseService implements ILeaveManagerService {

	@Override
	public Page findLeaveInfo(Map<String, Object> map, MedicalLeaveInfo leaveInfo, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveInfo a where 1=1 and a.eid = ? and a.user.id = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveInfo a where 1=1 and a.eid = ? and a.user.id = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		objectList.add(admin.getId());
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}

		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveInfo> leaveInfoList = new ArrayList<MedicalLeaveInfo>();
		for(Object obj : page.getResult()){
			MedicalLeaveInfo info = (MedicalLeaveInfo) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, info.getLeaveType());
			info.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(info);
		}
		page.setResult(leaveInfoList);
		return page;
	}

	@Override
	public Page findApproveLeave(Map<String, Object> map, MedicalLeaveApprove leave, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveApprove a where 1=1 and a.eid = ? and a.user.id = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveApprove a where 1=1 and a.eid = ? and a.user.id = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		objectList.add(admin.getId());
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}

		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveApprove> leaveInfoList = new ArrayList<MedicalLeaveApprove>();
		for(Object obj : page.getResult()){
			MedicalLeaveApprove approve = (MedicalLeaveApprove) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, approve.getLeaveType());
			approve.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(approve);
		}
		page.setResult(leaveInfoList);
		return page;
	}
	
	@Override
	public Page findApproveNotByLeave(Map<String, Object> map, MedicalLeaveNotBy notby, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveNotBy a where 1=1 and a.eid = ? and a.user.id = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveNotBy a where 1=1 and a.eid = ? and a.user.id = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		objectList.add(admin.getId());
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveNotBy> leaveInfoList = new ArrayList<MedicalLeaveNotBy>();
		for(Object obj : page.getResult()){
			MedicalLeaveNotBy approve = (MedicalLeaveNotBy) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, approve.getLeaveType());
			approve.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(approve);
		}
		page.setResult(leaveInfoList);
		return page;
	}
	
	@Override
	public Page findLeaveApproveInfo(Map<String, Object> map, MedicalLeaveInfo leaveInfo, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveInfo a where 1=1 and a.eid = ? and a.status = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveInfo a where 1=1 and a.eid = ? and a.status = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		objectList.add(SystemConfig.LEAVE_SUBMIT);
		
		if(StringUtils.isNotBlank(leaveInfo.getName())){
			String str = leaveInfo.getName().trim().replaceAll("_", "chr(95)").replaceAll("%", "chr(37)");
			statusSql.append(" and a.user.name like ? ");
			countSql.append(" and a.user.name like ? ");
			objectList.add("%"+str+"%");
		}
		
		if(StringUtils.isNotBlank(leaveInfo.getLeaveType())){
			String[] str = leaveInfo.getLeaveType().split(",");
			statusSql.append(" and (a.leaveType = ? ");
			countSql.append(" and (a.leaveType = ? ");
			objectList.add(str[0]);
			if(str.length > 1){
				for(int i=1;i<str.length;i++){
					statusSql.append(" or a.leaveType = ? ");
					countSql.append(" or a.leaveType = ? ");
					objectList.add(str[i]);
				}
			}
			statusSql.append(")");
			countSql.append(")");
		}
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveInfo> leaveInfoList = new ArrayList<MedicalLeaveInfo>();
		for(Object obj : page.getResult()){
			MedicalLeaveInfo info = (MedicalLeaveInfo) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, info.getLeaveType());
			info.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(info);
		}
		page.setResult(leaveInfoList);
		return page;
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean saveLeaveInfo(MedicalLeaveInfo leaveInfo, MedicalAdmin admin) {
		MedicalAdmin user = new MedicalAdmin();
		user.setId(admin.getId());
		leaveInfo.setUser(user);
		leaveInfo.setEid(admin.getEnterpriseId());
		leaveInfo.setStatus(SystemConfig.LEAVE_SUBMIT);
		Set<ConstraintViolation<Object>> errorInfo = ValidatorUtil.validateObj(leaveInfo);
		if(errorInfo.size() > 0) {
			return false;
		} else {
			return this.iBaseDao.saveObject(leaveInfo);
		}
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean editLeaveInfo(MedicalLeaveInfo leaveInfo) {
		MedicalLeaveInfo bean = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, leaveInfo.getId());
		bean.setStartTime(leaveInfo.getStartTime());
		bean.setEndTime(leaveInfo.getEndTime());
		bean.setDays(leaveInfo.getDays());
		bean.setLeaveType(leaveInfo.getLeaveType());
		bean.setDescription(leaveInfo.getDescription());
		bean.setStatus(SystemConfig.LEAVE_SUBMIT);
		Set<ConstraintViolation<Object>> errorInfo = ValidatorUtil.validateObj(bean);
		if(errorInfo.size() > 0) {
			return false;
		} else {
			return this.iBaseDao.saveObject(bean);
		}
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean saveEditLeaveInfo(MedicalLeaveNotBy notby) {
		MedicalLeaveNotBy notbyLeave = (MedicalLeaveNotBy) this.iBaseDao.getObject(MedicalLeaveNotBy.class, notby.getId());
		MedicalLeaveInfo info = new MedicalLeaveInfo();
		BeanUtils.copyProperties(notby, info);
		info.setUser(notbyLeave.getUser());
		info.setEid(notbyLeave.getEid());
		info.setCreateTime(new Date());
		info.setStatus(SystemConfig.LEAVE_SUBMIT);
		this.iBaseDao.deleteObject(notbyLeave);
		Set<ConstraintViolation<Object>> errorInfo = ValidatorUtil.validateObj(info);
		if(errorInfo.size() > 0) {
			return false;
		} else {
			return this.iBaseDao.addObject(info);
		}
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void deleteLeaveInfo(MedicalLeaveInfo bean) {
		String ids[] = bean.getId().split(",");
		if(ids.length == 1){
			this.iBaseDao.deleteObject(bean);
		}else{
			for(String id : ids){
				this.iBaseDao.updateHql("delete from MedicalLeaveInfo m where m.id = ? ", id);
			}
		}
	}

	@Override
	public Page findLeaveLogAll(Map<String, Object> map, MedicalLeaveApprove leaveInfo, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveApprove a where 1=1 and a.eid = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveApprove a where 1=1 and a.eid = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		
		if(StringUtils.isNotBlank(leaveInfo.getName())){
			statusSql.append(" and a.user.name like ? ");
			countSql.append(" and a.user.name like ? ");
			objectList.add("%"+leaveInfo.getName()+"%");
		}
		
		if(StringUtils.isNotBlank(leaveInfo.getLeaveType())){
			String[] str = leaveInfo.getLeaveType().split(",");
			statusSql.append(" and (a.leaveType = ? ");
			countSql.append(" and (a.leaveType = ? ");
			objectList.add(str[0]);
			if(str.length > 1){
				for(int i=1;i<str.length;i++){
					statusSql.append(" or a.leaveType = ? ");
					countSql.append(" or a.leaveType = ? ");
					objectList.add(str[i]);
				}
			}
			statusSql.append(")");
			countSql.append(")");
		}
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveApprove> leaveInfoList = new ArrayList<MedicalLeaveApprove>();
		for(Object obj : page.getResult()){
			MedicalLeaveApprove info = (MedicalLeaveApprove) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, info.getLeaveType());
			info.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(info);
		}
		page.setResult(leaveInfoList);
		return page;
	}
	
	@Override
	public Page findLeaveLogNotByAll(Map<String, Object> map, MedicalLeaveNotBy leaveInfo, MedicalAdmin admin) {
		StringBuilder statusSql = new StringBuilder("from MedicalLeaveNotBy a where 1=1 and a.eid = ? ");
		StringBuilder countSql = new StringBuilder("select count(*) from MedicalLeaveNotBy a where 1=1 and a.eid = ? ");
		
		List<Object> objectList = new ArrayList<Object>();
		objectList.add(admin.getEnterpriseId());
		
		if(StringUtils.isNotBlank(leaveInfo.getName())){
			statusSql.append(" and a.user.name like ? ");
			countSql.append(" and a.user.name like ? ");
			objectList.add("%"+leaveInfo.getName()+"%");
		}
		
		if(StringUtils.isNotBlank(leaveInfo.getLeaveType())){
			String[] str = leaveInfo.getLeaveType().split(",");
			statusSql.append(" and (a.leaveType = ? ");
			countSql.append(" and (a.leaveType = ? ");
			objectList.add(str[0]);
			if(str.length > 1){
				for(int i=1;i<str.length;i++){
					statusSql.append(" or a.leaveType = ? ");
					countSql.append(" or a.leaveType = ? ");
					objectList.add(str[i]);
				}
			}
			statusSql.append(")");
			countSql.append(")");
		}
		
		//排序
		String[] sortField = (String[]) map.get("sortField");
		String[] sortOrder = (String[]) map.get("sortOrder");
		if(StringUtils .isNotBlank(sortField[0]) && StringUtils.isNotBlank(sortOrder[0])){
			statusSql.append("order by a." + sortField[0] + " " + sortOrder[0]); 
		} else {
			statusSql.append("order by a.createTime desc ");
		}
		
		Page page = this.iBaseDao.getPage(ParamUtil.getInteger(map,"pageIndex",1),ParamUtil.getInteger(map, "pageSize", 20),
				map, countSql.toString(), statusSql.toString(), objectList);
		List<MedicalLeaveNotBy> leaveInfoList = new ArrayList<MedicalLeaveNotBy>();
		for(Object obj : page.getResult()){
			MedicalLeaveNotBy info = (MedicalLeaveNotBy) obj;
			MedicalKeyValue key1 = this.iBaseDao.getValueByKey(admin.getEnterpriseId(), SystemConfig.HM_SYSTEM_TYPE, info.getLeaveType());
			info.setLeaveTypeName(key1.getKeyValue());
			leaveInfoList.add(info);
		}
		page.setResult(leaveInfoList);
		return page;
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void saveApproveLeave(MedicalLeaveApprove leave) {
		String[] str = leave.getInfoId().split(",");
		if(str.length == 1){
			MedicalLeaveInfo info = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, leave.getInfoId());
			MedicalLeaveApprove approve = new MedicalLeaveApprove();
			BeanUtils.copyProperties(info, approve);
			this.iBaseDao.addObject(approve);
			this.iBaseDao.deleteObject(info);
		}else{
			for(String id : str){
				MedicalLeaveInfo info = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, id);
				MedicalLeaveApprove approve = new MedicalLeaveApprove();
				BeanUtils.copyProperties(info, approve);
				this.iBaseDao.deleteObject(info);
				this.iBaseDao.addObject(approve);
			}
		}
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public void saveNotByApproveLeave(MedicalLeaveNotBy notby) {
		String[] str = notby.getInfoId().split(",");
		if(str.length == 1){
			MedicalLeaveInfo info = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, notby.getInfoId());
			MedicalLeaveNotBy approve = new MedicalLeaveNotBy();
			BeanUtils.copyProperties(info, approve);
			this.iBaseDao.addObject(approve);
			this.iBaseDao.deleteObject(info);
		}else{
			for(String id : str){
				MedicalLeaveInfo info = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, id);
				MedicalLeaveNotBy approve = new MedicalLeaveNotBy();
				BeanUtils.copyProperties(info, approve);
				this.iBaseDao.addObject(approve);
				this.iBaseDao.deleteObject(info);
			}
		}
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	public boolean editLeaveBack(MedicalLeaveInfo info) {
		MedicalLeaveInfo bean = (MedicalLeaveInfo) this.iBaseDao.getObject(MedicalLeaveInfo.class, info.getId());
		bean.setStatus(SystemConfig.LEAVE_BACK);
		Set<ConstraintViolation<Object>> errorInfo = ValidatorUtil.validateObj(bean);
		if(errorInfo.size() > 0) {
			return false;
		} else {
			return this.iBaseDao.saveObject(bean);
		}
	}

	
}
